﻿using CustomComponents.CustomInputBox;
using ParkSaleForAdmin.Data;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

namespace ParkSaleForAdmin.Foundation
{

    public interface IBaseData<T>
    {
        T Parse(DatabaseData data);
    }

    public partial class DatabaseManager : Window
    {
        public DatabaseManager()
        {
            InitializeComponent();
        }
    }


    /// <summary>
    /// DatabaseManager.xaml 的交互逻辑
    /// </summary>
    public abstract class DatabaseWindows<T> : DatabaseManager where T : class, IBaseData<T>, new()
    {

        public int page = 0;
        public int per = 5;
        ObservableCollection<T> CollectionModelFile = new ObservableCollection<T>();
        protected virtual string[] values
        {
            get => fvalue;
        }
        protected virtual string[] titles
        {
            get => ftitle;
        }
        protected virtual string[] InputBoxTitle
        {
            get => ititle;
        }
        protected virtual string[] InputBoxValue
        {
            get => ivalue;
        }
        string[] bindname, ititle, ivalue, ftitle, fvalue;
        protected virtual string[] BindingName
        {
            get => bindname;
        }
        void findBindName(out string[] bindingname, out string[] inputtitle, out string[] inputvalue, out string[] titles, out string[] values)
        {
            List<string> binds = new List<string>();
            List<string> ititles = new List<string>();
            List<string> ivalues = new List<string>();
            List<string> ftitles = new List<string>();
            List<string> fvalues = new List<string>();
            Type type = typeof(T);
            var arr = type.GetProperties();
            for (int i = 0; i < arr.Length; i++)
            {
                DataToUIAttribute[] att = (DataToUIAttribute[])arr[i].GetCustomAttributes(typeof(DataToUIAttribute), false);
                if (att != null)
                {
                    if (att.Length > 0)
                    {
                        var a = att[0];
                        if (a.Editable)
                        {
                            ititles.Add(a.Title);
                            ivalues.Add(a.Value != null ? a.Value : arr[i].Name);
                        }
                        ftitles.Add(a.Title);
                        fvalues.Add(a.Value != null ? a.Value : arr[i].Name);
                        binds.Add(arr[i].Name);
                        continue;
                    }
                }
            }
            bindingname = binds.ToArray();
            inputtitle = ititles.ToArray();
            inputvalue = ivalues.ToArray();
            titles = ftitles.ToArray();
            values = fvalues.ToArray();
        }
        public abstract string TableName
        {
            get;
        }
        public abstract string DeleteStr(T obj);
        public abstract string AppendStr(T obj);
        public abstract string ChangeStr(T obj);
        protected void BeginToCreate()
        {
            InitializeComponent();
            findBindName(out bindname, out ititle, out ivalue, out ftitle, out fvalue);
            this.add.Click += add_Click;
            this.delete.Click += delete_Click;
            this.change.Click += change_Click;
            this.pagechange_last.Click += pagechange_last_Click;
            this.pagechange_next.Click += pagechange_Click;
            this.find.Click += Find_Click;
            this.jump.Click += Jump_Click;
            notice.MouseDoubleClick += Notice_MouseDoubleClick;
            
            if (values.Length != titles.Length || values.Length != BindingName.Length || titles.Length != BindingName.Length)
                throw new Exception("错误对象个数");
            if (InputBoxTitle.Length != InputBoxValue.Length)
            {
                throw new Exception("输入区域错误对象个数");
            }
            for (int i = 0; i < BindingName.Length; i++)
            {
                var item = new GridViewColumn() { Width = 140,DisplayMemberBinding=new Binding(BindingName[i]),Header=titles[i] };

                //FrameworkElementFactory factoryText =new FrameworkElementFactory(typeof(Label));
                //factoryText.SetValue(Label.ContentProperty, titles[i]);
                //factoryText.AddHandler(Label.MouseDoubleClickEvent,Delegate.CreateDelegate(typeof(MouseButtonEventHandler),this, "Header_MouseUp"));
                //item.HeaderTemplate = new DataTemplate();
                //item.HeaderTemplate.VisualTree = factoryText;
                this.Columns.Columns.Add(item);
            }

            InitInputBox();
            UpdatePage();
        }

        private void Jump_Click(object sender, RoutedEventArgs e)
        {
            InputBox box = new InputBox();
           string t= box.Show("请输入页数", "输入");
            try
            {
                int v = int.Parse(t);
                UpdatePage(v);
            }
            catch
            {
                MessageBox.Show("不是数字，请输入整数", "请输入错误",MessageBoxButton.OK,MessageBoxImage.Error);
            }

        }

        private void Notice_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            UpdatePage(page);
        }

        private void Find_Click(object sender, RoutedEventArgs e)
        {
            Type type = typeof(T);
            SingleOptionInputBox input = new SingleOptionInputBox(titles);
            List<T> found = new List<T>();
            int select= input.Show("请选择根据的数据", "输入");
            if (select >= 0)
            {
                InputBox text = new InputBox();
                string v= text.Show("请输入您指定的值", "输入");

                string col = BindingName[select];
                foreach (var i in CollectionModelFile)
                {
                    if (type.GetProperty(col).GetValue(i).ToString().Equals(v))
                    {
                        found.Add(i);
                    }
                }
                listView.ItemsSource = found;
            }
            

        }

        protected virtual void InitInputBox()
        {
            for (int i = 0; i < InputBoxTitle.Length; i++)
            {
                inputbox.Items.Add(new InputPanel() { Name = InputBoxTitle[i], Tag = InputBoxValue[i] });
            }
        }
        bool updating = false;
        public bool Updating
        {
            get => updating;
            set
            {
                if (value)
                {
                    pagechange_next.IsEnabled = false;
                    pagechange_last.IsEnabled = false;
                }
                else
                {
                    pagechange_next.IsEnabled = true;
                    pagechange_last.IsEnabled = true;
                }
                updating = value;
            }
        }

        protected virtual int UpdateResult(object objs)
        {
            if (objs != null)
            {
                var datas = (List<DatabaseData>)objs;
                if (datas.Count > 0)
                {
                    CollectionModelFile.Clear();
                    foreach (var d in datas)
                    {
                        CollectionModelFile.Add(new T().Parse(d));
                    }
                    listView.ItemsSource = CollectionModelFile;
                    return 1;
                }
                else
                {
                    return 0;
                }

            }
            else
                return -1;
        }
        public void UpdatePage(int page = 0, Action<int> afterupdate = null)
        {
            if (!Updating)
            {
                Updating = true;

                SystemManager.Request<List<DatabaseData>>(SuUserRequestInfo.s_FindValue, new string[] { TableName, $"Limit {page * per},{per}" }, SystemManager.Admin, delegate (Object objs)
                {
                    int handle = UpdateResult(objs);
                    if (handle == 1)
                    {
                        this.page = page;
                        notice.Content = $"页数：{page}";
                    }
                    if (afterupdate != null)
                        afterupdate(handle);
                    Updating = false;
                });
            }

        }

        public abstract void DeleteResult(Object result);
        public abstract void AppendResult(Object result);

        public abstract void ChangeResult(Object result);
        protected virtual void delete_Click(object sender, RoutedEventArgs e)
        {
            if (listView.SelectedItem != null)
            {
                var detial = (T)listView.SelectedItem;
                SystemManager.Request<int>(SuUserRequestInfo.s_DeleteValue, new string[] { TableName, DeleteStr(detial) }, SystemManager.Admin, delegate (Object obj)
                 {
                     DeleteResult(obj);
                 }
                );
            }
            else
            {
                MessageBox.Show("请选择一项进行删除", "提示");
            }
        }

        private void pagechange_Click(object sender, RoutedEventArgs e)
        {
            UpdatePage(page + 1, delegate (int isdone)
            {
                if (isdone == 0)
                {
                    MessageBox.Show("无更多数据", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
                else if (isdone == -1)
                {
                    MessageBox.Show("网络错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            });
        }

        private void pagechange_last_Click(object sender, RoutedEventArgs e)
        {
            if (page - 1 >= 0)
            {
                UpdatePage(page - 1);
            }
            else
            {
                MessageBox.Show("已到第一页", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
            }

        }

        protected virtual bool EachArgForAppend(string n, string value)
        {

            return false;
        }
        protected virtual int StandAppendArgsCount
        {
            get => 2 + InputBoxValue.Length * 2;
        }

        private void add_Click(object sender, RoutedEventArgs e)
        {
            List<string> args = new List<string>(new string[] { TableName, AppendStr(null) });
            foreach (var item in inputbox.Items)
            {
                var panel = (InputPanel)item;
                string n = panel.Tag.ToString();
                if (panel.Value == null)
                {
                    MessageBox.Show("空输入错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    break;
                }
                else
                {
                    if (panel.Value.Length > 0)
                    {

                        if (!EachArgForAppend(n, panel.Value))
                        {
                            break;
                        }
                        else
                        {
                            args.Add(n); args.Add(panel.Value);
                            continue;
                        }
                    }
                    else
                    {
                        MessageBox.Show("空输入错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        break;
                    }

                }
            }
            if (args.Count == StandAppendArgsCount)
            {
                SystemManager.Request<int>(SuUserRequestInfo.s_AppendValue, args.ToArray(), SystemManager.Admin, AppendResult);
            }
            else
            {
                MessageBox.Show("录入失败，参数错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }

        }
        protected virtual bool ValueChangeIsOk(string n, string value)
        {

            return EachArgForAppend(n, value);
        }

        protected virtual void change_Click(object sender, RoutedEventArgs e)
        {
            if (listView.SelectedItem != null)
            {
                var detial = (T)listView.SelectedItem;

                SingleOptionInputBox box = new SingleOptionInputBox(InputBoxTitle);
                var textinput = new InputBox();
                int select = box.Show("请选择要修改的项", "修改");
                if (select >= 0)
                {
                    string value = textinput.Show("请输入要修改的值", "修改");
                    if (value.Length > 0)
                    {
                        if (ValueChangeIsOk(InputBoxValue[select], value))
                            SystemManager.Request<int>(SuUserRequestInfo.s_ChangeValue, new string[] { TableName, ChangeStr(detial), InputBoxValue[select], value }, SystemManager.Admin, ChangeResult);
                        else
                        {
                            MessageBox.Show("修改的值有误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);

                        }
                    }

                    else
                    {
                        MessageBox.Show("空输入错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                box.Close();
            }
            else
            {
                MessageBox.Show("请点击一项进行选择", "提示");
            }
        }

    }
}
